#include "Face.h"

Face::Face() {
    this->state = NULL;
    this->name = NULL;
    this->allowUpdate = true;
    this->autorelease();
    
    this->states = __Dictionary::create();
    CC_SAFE_RETAIN(this->states);
}

Face::~Face() {
    CC_SAFE_RELEASE(this->states);
}

void Face::onEnter() {
    CCSprite::onEnter();
}

void Face::onExit() {
    CCSprite::onExit();
    this->removeAllChildrenWithCleanup(true);
}

bool Face::init() {
    return Sprite::init();
}

bool Face::initWithFile(const std::string& filename) {
    return Sprite::initWithFile(filename);
}

bool Face::initWithSpriteFrameName(const std::string& spriteFrameName) {
    return Sprite::initWithSpriteFrameName(spriteFrameName);
}

Action* Face::getState() {
    return this->state;
}

Action* Face::getState(const std::string& stateName) {
    return (Action*) this->states->objectForKey(stateName);
}

void Face::setState(Action* s) {
    if (this->state != s) {
        if (this->state != NULL) {
            this->stopAction(state);
        }
        if (s != NULL) {
            this->state = s;
            this->runAction(this->state);
        } else {
            this->state = NULL;
        }
    }
}

void Face::setState(const std::string& stateName) {
    this->setState(this->getState(stateName));
}

void Face::registerState(const std::string& stateName, const std::string& patternName) {
    this->registerState(stateName, createState(patternName, 0.8f, true));
}

void Face::registerState(const std::string& stateName, Action* action) {
    if (action != NULL) {
        this->states->setObject(action, stateName);
    }
}

void Face::removeState(const std::string &stateName) {
    this->states->removeObjectForKey(stateName);
}

Action* Face::createState(const std::string&  patternName, float frameDuration, bool forever) {
    return this->createState(patternName, 4, frameDuration, forever, false);
}

Action* Face::createState(const std::string&  patternName, int frameNumber, float frameDuration, bool forever, bool reverse) {
    return this->createState(patternName, 1, frameNumber, frameDuration, forever, reverse);
}

Action* Face::createState(const std::string& patternName, int startFrame, int endFrame, float frameDuration, bool forever, bool reverse) {
    Vector<SpriteFrame*> *framesVector = this->createFrameVector(patternName,startFrame,endFrame);
    if (reverse) {
        int framesSize = framesVector->size();
        for(int i = framesSize - 1; i >= 0; i--) {
            framesVector->pushBack(framesVector->at(i));
        }
    }
    
    float delay = frameDuration / framesVector->size();
    Animation* animation = Animation::createWithSpriteFrames(*framesVector, delay);
    Animate* animate = Animate::create(animation);
    Action* action = NULL;
    if (forever) {
        action = RepeatForever::create(animate);
    } else {
        action = (Action*) animate;
    }
    delete framesVector;
    return action;
}

Vector<SpriteFrame*>* Face::createFrameVector(const std::string& patternName, int startFrame, int endFrame) {
    SpriteFrameCache *spriteFrameCache = SpriteFrameCache::getInstance();
    Vector<SpriteFrame*>*framesVector = new Vector<SpriteFrame*>;
    char frameName[128];
    for(int i = startFrame; i <= endFrame; i++){
        sprintf(frameName, patternName.c_str(), i);
        framesVector->pushBack(spriteFrameCache->getSpriteFrameByName(frameName));
    }
    return framesVector;
}